package order.server;

import jakarta.annotation.PostConstruct;
import order.config.BeanConfig;
import order.dao.OrderInfo;
import order.dao.ProductInfo;
import order.mapper.OrderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EurekaServiceInstance;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Service
public class OrderServer {

    @Autowired
    OrderMapper orderMapper;
    @Autowired
    BeanConfig beanConfig;
    @Autowired
    RestTemplate restTemplate;
    @Autowired
    DiscoveryClient discoveryClient;

    private List<ServiceInstance> instances;

    private AtomicInteger atomicInteger = new AtomicInteger(1);

    //在这个对象被创建之后立刻调用 在Autowired之后
    @PostConstruct
    public void init() {
        instances = discoveryClient.getInstances("product-server");
    }

    /**
     * 向product服务也发起了一个请求获取到了对应的商品信息
     */
    public OrderInfo getOrderById1(int orderId) {
        OrderInfo orderInfo = orderMapper.selectById(orderId);

        String url = "http://localhost:8081/product/" + orderInfo.getProductId();

        RestTemplate restTemplate = beanConfig.restTemplate();

        ProductInfo forObject = restTemplate.getForObject(url, ProductInfo.class);

        orderInfo.setProductInfo(forObject);

        return orderInfo;
    }

    /**
     * 从eureka中来获取一个product-server服务
     * 服务发现
     */
    public OrderInfo getOrderById2(int orderId) {

        OrderInfo orderInfo = orderMapper.selectById(orderId);

        //在eureka中获取到服务
//        instances = discoveryClient.getInstances("product-server");

        //使用负载均衡来平均的调用服务
        ServiceInstance instance = loadBalance();
//        和ServiceInstance一样，只不过是还实现了toString和equals，hashCode方法
//        EurekaServiceInstance instance = (EurekaServiceInstance) instances.get(0);

        String url = instance.getUri() + "/product/" + orderInfo.getProductId();

        ProductInfo forObject = restTemplate.getForObject(url, ProductInfo.class);

        orderInfo.setProductInfo(forObject);

        return orderInfo;
    }

    ServiceInstance loadBalance() {
        int i = atomicInteger.incrementAndGet();
        return instances.get(i % instances.size());
    }


    //使用注解@LoadBalanced来均衡负载
    public OrderInfo getOrderById(int orderId) {

        OrderInfo orderInfo = orderMapper.selectById(orderId);

        //在eureka中获取到服务
//        instances = discoveryClient.getInstances("product-server");
        //他会根据这个product-server来获取到对应的服务 通过getHost来得到
        String url = "http://product-server/product/"+ orderInfo.getProductId();

        ProductInfo forObject = restTemplate.getForObject(url, ProductInfo.class);

        orderInfo.setProductInfo(forObject);

        return orderInfo;
    }
}